package mx.iteso.comp.logo;

import java.awt.Color;
import java.util.Vector;

import mx.iteso.comp.logo.analysis.*;
import mx.iteso.comp.logo.node.*;


class Translator extends DepthFirstAdapter
{
	public void caseAGword(AGword node)
    {
        inAGword(node);
        if(node.getWord() != null&&node.getIdentifier() != null)
        {
        	String concat = node.getIdentifier().getText().trim();
        	if (node.getGidentlist() instanceof AIdentListGidentlist)
        	{
        		AIdentListGidentlist list = (AIdentListGidentlist)node.getGidentlist();
        		while (list.getGidentlist() instanceof AIdentListGidentlist)
        		{
        			concat+=list.getIdentifier().getText().trim();
        			list = (AIdentListGidentlist) list.getGidentlist();        			
        		}
        		concat+=list.getIdentifier().getText().trim();
        		concat+=((AIdentGidentlist)list.getGidentlist()).getIdentifier();
        	}
        	else
        		concat+=((AIdentGidentlist)node.getGidentlist()).getIdentifier();
        	Conector.setOutput(concat);
        }
        outAGword(node);
    }
	public void caseAGint(AGint node)
    {
        inAGint(node);
        if(node.getInt() != null&&node.getGeval() != null)
        {
        	if (node.getGeval()instanceof AIntGeval)
        		Conector.setOutput(""+Math.round(Math.floor(Integer.parseInt(((AIntGeval)node.getGeval()).getInteger().getText().trim()))));
        	else
        		Conector.setOutput(""+Math.round(Math.floor(Double.parseDouble(((ADobGeval)node.getGeval()).getDouble().getText().trim()))));
        }
        outAGint(node);
    }
	
	public void caseAForwardGgraphics(AForwardGgraphics node)
    {
        inAForwardGgraphics(node);
        if(node.getGforward() != null)
        {
            Integer dist = 0;
            if (node.getGforward() instanceof AForwardGforward)
            dist = Integer.parseInt(((AForwardGforward)node.getGforward()).getInteger().getText().trim());
            else
            dist = Integer.parseInt(((AForwardGforward)node.getGforward()).getInteger().getText().trim());
            //dist<0 distancia negativa
            if (dist<0)Conector.setTurtleAngle(180);
            Conector.add(Math.abs(dist));
            if (dist<0)Conector.setTurtleAngle(180);
        }
        outAForwardGgraphics(node);
    }
    public void caseABackGgraphics(ABackGgraphics node)
    {
        inABackGgraphics(node);
        if(node.getGback() != null)
        {
        	Integer dist = 0;
            if (node.getGback() instanceof ABackGback)
            	dist = Integer.parseInt(((ABackGback)node.getGback()).getInteger().getText().trim());
            else
                dist = Integer.parseInt(((ABackGback)node.getGback()).getInteger().getText().trim());
        	Conector.setTurtleAngle(180);
            if (dist<0)Conector.setTurtleAngle(180);
            Conector.add(Math.abs(dist));
            if (dist<0)Conector.setTurtleAngle(180);
        	Conector.setTurtleAngle(180);
        }
        outABackGgraphics(node);
    }
    public void caseALeftGgraphics(ALeftGgraphics node)
    {
        inALeftGgraphics(node);
        if(node.getGleft() != null)
        {
        	Integer degree = 0;
        	if (node.getGleft() instanceof ALeftGleft)
        		degree = Integer.parseInt(((ALeftGleft)node.getGleft()).getInteger().getText().trim());
        	else
        		degree = Integer.parseInt(((ALeftGleft)node.getGleft()).getInteger().getText().trim());
        	Conector.setTurtleAngle((degree*-1));
        }
        outALeftGgraphics(node);
    }
    public void caseARigthGraphics(ARigthGgraphics node)
    {
        inARigthGgraphics(node);
        if(node.getGright() != null)
        {
        	Integer degree = 0;
        	if (node.getGright() instanceof ARigthGright)
        		degree = Integer.parseInt(((ARigthGright)node.getGright()).getInteger().getText().trim());
        	else
        		degree = Integer.parseInt(((ARigthGright)node.getGright()).getInteger().getText().trim());
        	Conector.setTurtleAngle(degree);
        }
        outARigthGgraphics(node);
    }
    //@SuppressWarnings("unchecked")
    public void caseAGrepeat(AGrepeat node)
    {
        inAGrepeat(node);
        if(node.getGinstructionlist() != null)
        {
        	for (int i = 0 ; i < Integer.parseInt(node.getInteger().getText().trim()); i++)
        		node.getGinstructionlist().apply(this);
        }
        outAGrepeat(node);
    }
    public void caseAGhome(AGhome node)
    {
        inAGhome(node);
        if(node.getHome() != null)
        {
            Conector.setTurtleAngle(-Conector.getTurtleAngle());
            Conector.add(new Puntos(Conector.centerX,Conector.centerY, false));
        }
        outAGhome(node);
    }
    
    public void caseAClrGgraphics(AClrGgraphics node)
    {
        inAClrGgraphics(node);
        if(node.getGclearscreen() != null)
        {
        	Puntos turtlepos = Conector.getPuntos().get(Conector.getCantPuntos()-1);
        	turtlepos = new Puntos(turtlepos.X(), turtlepos.Y(), false);
        	Conector.clearPuntos();
        	Conector.add(turtlepos);
        	Conector.clearOutput();
        }
        outAClrGgraphics(node);
    }
    
    public void caseAGadd(AGadd node)
    {
        inAGadd(node);
        double sum,sum1 = 0,sum2;
        if(node.getSum() != null&&node.getA() != null)
        {
        	 sum1 = 0;
        	if (node.getA() instanceof AIntGeval)
        		sum1 += Integer.parseInt(((AIntGeval)node.getA()).getInteger().getText().trim());
        	else
        		sum1 += Double.parseDouble(((ADobGeval)node.getA()).getDouble().getText().trim());
        	//Conector.setOutput(""+sum);      		
        }
        if(node.getSum() != null&&node.getA() != null)
        {
        	sum2 = 0;
        	if (node.getB() instanceof AIntGeval)
        		sum2 += Integer.parseInt(((AIntGeval)node.getB()).getInteger().getText().trim());
        	else
        		sum2 += Double.parseDouble(((ADobGeval)node.getB()).getDouble().getText().trim());
        	sum = sum1+sum2;
        	Conector.setOutput(""+sum);      		
        }
        outAGadd(node);
    }
    
    public void caseAGsub(AGsub node)
    {
        inAGsub(node);
        double sub,sub1 = 0,sub2;
        if(node.getDifference() != null&&node.getA() != null)
        {
        	 sub1 = 0;
        	if (node.getA() instanceof AIntGeval)
        		sub1 += Integer.parseInt(((AIntGeval)node.getA()).getInteger().getText().trim());
        	else
        		sub1 += Double.parseDouble(((ADobGeval)node.getA()).getDouble().getText().trim());
        	//Conector.setOutput(""+sum);      		
        }
        if(node.getDifference() != null&&node.getA() != null)
        {
        	sub2 = 0;
        	if (node.getB() instanceof AIntGeval)
        		sub2 += Integer.parseInt(((AIntGeval)node.getB()).getInteger().getText().trim());
        	else
        		sub2 += Double.parseDouble(((ADobGeval)node.getB()).getDouble().getText().trim());
        	sub = sub1+sub2;
        	Conector.setOutput(""+sub);      		
        }
        outAGsub(node);
    }
    public void caseAPSetx(AGsetx node)
    {
        inAGsetx(node);
        if(node.getSetx() != null && node.getInteger() != null)
        {
        	Conector.add(new Puntos(Conector.centerX+Integer.parseInt(node.getInteger().getText().trim()),Conector.getPuntos().get(Conector.getPuntos().size()-1).Y(),false));
        }
        outAGsetx(node);
    }
    public void caseAPSety(AGsety node)
    {
        inAGsety(node);
        if(node.getSety() != null && node.getInteger() != null)
        {
        	Conector.add(new Puntos(Conector.getPuntos().get(Conector.getPuntos().size()-1).X(),Conector.centerY+Integer.parseInt(node.getInteger().getText().trim()),false));
        }
        outAGsety(node);
    }
    public void caseAGand(AGand node)
    {
        inAGand(node);
        if(node.getAnd() != null&&node.getVal1() != null&&node.getVal2() != null)
        {
        	if (Boolean.getBoolean(node.getVal1()) && Boolean.getBoolean(node.getVal2()))
        		Conector.setOutput("true");
        	else
        		Conector.setOutput("false");
        }
        outAGand(node);
    }
    public void caseAPOr(AGor node)
    {
        inAGor(node);
        if(node.getOr() != null&&node.getVal1() != null&&node.getVal2() != null)
        {
        	if (Boolean.getBoolean(node.getVal1())|| Boolean.getBoolean(node.getVal2()))
        		Conector.setOutput("true");
        	else
        		Conector.setOutput("false");    		
        }
        outAGor(node);
    }
   /* public void caseAGnot(AGnot node)
    {
        inAGnot(node);
        if(node.getNot() != null&&node.getNot() != null)
        {
    		if (Boolean.getBoolean(node.getNot()))
       			Conector.setOutput("false");
    		else
        		Conector.setOutput("true");        	
        }
        outAGnot(node);
    }*/
    
    public void caseAGmodulo(AGmodulo node)
    {
        inAGmodulo(node);
        if(node.getModulo() != null&&node.getDiv() != null&&node.getDiv() != null)
        {
        	Conector.setOutput(""+(int)(Integer.parseInt(node.getDiv().getText().trim())%Integer.parseInt(node.getDiv().getText().trim())));
        }
        outAGmodulo(node);
    }
    
    public void caseAGround(AGround node)
    {
        inAGround(node);
        if(node.getRound() != null && node.getGeval() != null)
        {
            if (node.getGeval() instanceof AIntGeval )
            	Conector.setOutput(((AIntGeval)node.getGeval()).getInteger().getText().trim());
            else
            	Conector.setOutput(""+Math.round(Double.parseDouble(((ADobGeval)node.getGeval()).getDouble().getText().trim())));
            
        }
        outAGround(node);
    }
      
    public void caseARunGinstructionlist(ARunGinstructionlist node)
    {
        inARunGinstructionlist(node);
        if(node.getRun() != null&&node.getLKey() != null&&node.getGinstructionlist() != null&&node.getRKey() != null&&node.getSemi() != null)
        {
            node.getGinstructionlist().apply(this);
        }
        outARunGinstructionlist(node);
    }
    
}